package com.whg.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @Author whg
 * @create 2022/9/27 17:05
 * @description：
 */
public class CustomRealm extends AuthorizingRealm {

    private final Map<String,String> userInfoMap = new HashMap<>();
    {
        userInfoMap.put("xdclass","123");
        userInfoMap.put("jack","456");
    }

    private final Map<String,Set<String>> userRoleMap = new HashMap<>();
    {
        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();

        /*set1.add("video:find");
        set1.add("video:buy");

        set2.add("video:add");
        set2.add("video:delete");*/

        set1.add("root");
        set1.add("admin");

        set2.add("user");

        userRoleMap.put("xdclass",set1);
        userRoleMap.put("jack",set2);
    }

    private final Map<String,Set<String>> rolePermMap = new HashMap<>();
    {
        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();

        set1.add("video:find");
        set1.add("video:buy");

        set2.add("video:add");
        set2.add("video:delete");

        rolePermMap.put("user",set1);
        rolePermMap.put("admin",set2);
    }


    /**
     * 进行权限校验的时候调用
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        System.out.println("鉴权 doGetAuthorizationInfo");

        String name = (String) principalCollection.getPrimaryPrincipal();
        //模拟从数据库得到用户的角色信息
        Set<String> roles = getRolesByUserNameFromDB(name);
        //模拟从数据库得到用户的权限信息
        Set<String> perms = getPermsByRolesFromDB(roles);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(perms);
        return simpleAuthorizationInfo;
    }

    /**
     * 用户登录的时候调用
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        System.out.println("认证 doGetAuthenticationInfo");

        //从token获取身份信息，token代表用户输入的信息
        String name = (String)authenticationToken.getPrincipal();
        //模拟从数据库中得到用户的密码
        String pwd = getPwdByUserNameFromDB(name);

        if(null == pwd || "".equals(pwd)){
            return null;
        }
        //主体名：principal
        //凭证句柄：credential
        SimpleAuthenticationInfo simpleAuthenticationInfo =
                new SimpleAuthenticationInfo(name,pwd,this.getName());
        return simpleAuthenticationInfo;
    }

    private String getPwdByUserNameFromDB(String name){
        return userInfoMap.get(name);
    }

    private Set<String> getRolesByUserNameFromDB(String name){
        return userRoleMap.get(name);
    }

    private Set<String> getPermsByRolesFromDB(Set<String> roles){
        Set<String> perms = new HashSet<>();
        for(String role : roles){
            if(null != rolePermMap.get(role) && rolePermMap.get(role).size() > 0){
                perms.addAll(rolePermMap.get(role));
            }
        }
        return perms.size() == 0 ? null : perms;
    }
}
